<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>从化绿波-时段配置</title>
  <link href="../../css/index.css" rel="stylesheet">
  <style>
    .drawer-content {
      display: block;
    }
  </style>
</head>

<body>
  <div class="page-container" id="time-config">
    <div class="page-select">
      <div v-for="item in pageTab" @click="changeTab(item)" :key="item.key" class="select-item"
        :class="item.key === 'time-config' ? 'active-select': ''">
        {{item.label}}
      </div>
      <img class="login-out" src="../../assets/exit.png" alt="退出登录" title="退出登录" @click="handleLoginOut" />
    </div>
    <div class="iframe-container">
      <div class="page-warp">
        <div class="message" :class="message.type" v-if="message.text">{{message.text}}</div>
        <template v-if="alert.text">
          <div class="dialog-cover alert-dialog-cover"></div>
          <div class="alert-dialog dialog">
            <div class="dialog-title alert-dialog-title">
              提示
            </div>
            <div class="dialog-content">
              {{alert.text}}
            </div>
            <div class="dialog-footer alert-dialog-footer">
              <template v-if="alert.type === MESSAGE_TYPE.ALERT">
                <button class="primary-btn" @click="cancelConfirm">确定</button>
              </template>
              <template v-if="alert.type === MESSAGE_TYPE.CONFIRM">
                <button class="cancel-btn" @click="cancelConfirm">取消</button>
                <button class="primary-btn" @click="handleConfirm(alert)">确定</button>
              </template>
            </div>
          </div>
        </template>
        <div class="table-content">
          <table border="1">
            <tr>
              <th class="area-title">子区</th>
              <th class="area-title">时段</th>
              <th class="area-title">开关</th>
              <th class="area-title">方案</th>
            </tr>
            <template v-for="item in timeConfigList">
              <tr class="center" :class="isOdd(item.master) ? 'odd' : 'even'">
                <td :rowspan="item.rowNum" v-if="item.isFirst">
                  {{item.master}}
                  <img src="../../assets/bianji.png" alt="编辑" @click="handleEdit(item)">
                </td>
                <td>{{item.time}}</td>
                <td>
                  <div :class="['checkbox circle', {'checked': item.enable}]"></div>
                </td>
                <td>{{item.plno}}</td>
              </tr>
            </template>
            <tr></tr>
            <tr v-if="loading.table">
              <th colspan="15">
                <img src="../../assets/jiazai.png" class="loading" />
              </th>
            </tr>
          </table>
        </div>
        <template v-if="editData.length">
          <div class="dialog-cover"></div>
          <div class="drawer">
            <div class="drawer-title">
              <div>
                子区：【{{editData[0].master}}】 时段表配置
              </div>
              <div @click="handleClose">
                <img src="../../assets/guanbi.png" />
              </div>
            </div>
            <div class="drawer-content">
              <div>
                <table border="1">
                  <tr>
                    <th class="area-title">时段</th>
                    <th class="area-title">开关</th>
                    <th class="area-title">方案</th>
                    <th class="area-title">操作</th>
                  </tr>
                  <template v-for="(item, index) in editData">
                    <tr class="center">
                      <td>
                        <input type="time" id="timePicker" v-model="item.startTime"
                          @blur="handleChangeTime(item, 'startTime')">
                        <input type="time" id="timePicker" v-model="item.endTime"
                          @blur="handleChangeTime(item, 'endTime')">
                      </td>
                      <td>
                        <div :value="item.enable" @click="item.enable = !item.enable"
                          :class="['checkbox pointer', {'checked': item.enable}]"></div>
                      </td>
                      <td>
                        <select v-model="item.plno">
                          <option v-for="item in canUseScheme" :key="item.key" :value="item.key"
                            :disabled="item.disabled">{{item.key}}</option>
                        </select>
                      </td>
                      <td>
                        <button class="del-btn-text" @click="handleRemove(index)">移除</button>
                        <button @click="handleAdd(index)">新增</button>
                      </td>
                    </tr>
                  </template>
                </table>
              </div>
            </div>
            <div class="drawer-footer">
              <button class="cancel-btn" @click="handleClose">取消</button>
              <button class="primary-btn" @click="handleSave">
                <img v-if="loading.save" src="../../assets/jiazai.png" class="loading" />保存</button>
            </div>
          </div>
        </template>
      </div>
    </div>
  </div>

</body>
<script src="../../js/vue3.js"></script>
<script src="../../js/api/secondEdition.js"></script>
<script src="../../config.js"></script>
<script src="../../js/dict/schemeConfig.js"></script>
<script src="../../js/method.js"></script>

<script>
  const { createApp, ref, nextTick, reactive, onMounted, onUnmounted, watch, computed } = Vue
  const app = createApp({
    setup() {
      const MESSAGE_TYPE = {
        'SUCCESS': 'success',
        'INFO': 'info',
        'ALERT': 'alert',
        'ERROR': 'error',
        'CONFIRM': 'confirm'
      }

      const loading = reactive({
        table: false, // 刷新时段
        save: false
      })

      const message = reactive({
        type: '',
        text: ''
      })

      const alert = reactive({
        type: '',
        text: '',
        methods: '',
        item: ''
      })

      // 弹窗消息1.5秒消失
      watch(
        () => message.text,
        () => {
          if (message.text) {
            setTimeout(() => {
              message.text = ''
            }, 2000)
          }
        }
      )

      const PAGE_TYPE = {
        'VIEW': 'view',
        'EDIT': 'edit'
      }
      // 处理模拟数据
      const apiPreFix = computed(() => {
        return isMock ? '' : apiUrl
      })

      // 处理模拟数据
      const api = computed(() => {
        return isMock ? mockApi : realApi
      })

      const timeConfigList = ref([])
      const originData = ref([])
      // 获取子区的时段方案配置
      const getTimeConfig = () => {
        fetch(apiPreFix.value + api.value.getEnableTime)
          .then(res => res.json())
          .then(res => {
            originData.value = res
            initData(originData.value)
          })
      }

      const initData = (data) => {
        subData.value = JSON.parse(JSON.stringify(SUB_LIST.value))
        subData.value.forEach(item => item.child = [])
        data.forEach(item => {
          const index = subData.value.findIndex(ele => ele.master === item.master)
          if (index > -1) {
            subData.value[index].child.push(item)
          }
        })
        timeConfigList.value = transformData(subData.value)
      }

      // 获取行的索引值
      const isOdd = computed(() => {
        return (master) => {
          const result = subData.value.findIndex(item => item.master === master)
          return result % 2 === 0
        }
      })

      // 数据合并转换
      const transformData = (sortData) => {
        let data = []
        sortData?.forEach((element, eleIndex) => {
          element.child.forEach((item, itemIndex) => {
            data.push({
              ...element,
              ...item,
              isFirst: itemIndex === 0, // 是否子区的第一条数据，第一条数据展示子区
              rowNum: element.child?.length || 1 // 子区的合并行数
            })
          })
          if (element.child.length === 0) {
            data.push({
              ...element,
              isFirst: true, // 是否子区的第一条数据，第一条数据展示子区
              rowNum: 1, // 子区的合并行数
            })
          }
        })
        return data
      }

      const editData = ref([])
      // 进入编辑状态
      const handleEdit = (item) => {
        editData.value = originData.value.filter(ele => ele.master === item.master)
        if (editData.value.length) {
          editData.value.forEach(item => {
            const timeSplit = item.time.split('-')
            item.startTime = timeSplit[0]
            item.endTime = timeSplit[1]
          })
        }
        else {
          editData.value.push({
            ...defaultTimeItem,
            master: item.master
          })
        }
        currentPlnoList()
      }

      // 关闭弹窗
      const handleClose = () => {
        editData.value = []
      }

      const dateInit = (date) => {
        return new Date(`2022-01-01 ${date}:00`)
      }
      // 判断两个时段是否交叉
      const isOverlap = (a, b) => {
        return dateInit(a.startTime) < dateInit(b.endTime) && dateInit(a.endTime) > dateInit(b.startTime);
      }

      // 判断多个时间段是否有交叉
      const hasOverlap = (timeRanges) => {
        for (let i = 0; i < timeRanges.length; i++) {
          for (let j = i + 1; j < timeRanges.length; j++) {
            if (isOverlap(timeRanges[i], timeRanges[j])) {
              return timeRanges[i];
            }
          }
        }
        return false;
      }

      // 保存时段
      const handleSave = () => {
        let flag = false
        editData.value.forEach(item => {
          if (!item.startTime || !item.endTime || !item.plno) {
            flag = !(!item.startTime && !item.endTime && !item.plno)
          }
          else {
            item.time = `${item.startTime}-${item.endTime}`
          }
        })
        console.log('flag', flag);

        if (flag) {
          message.type = MESSAGE_TYPE.ALERT
          message.text = '请完整填写各时段的运行时间和方案信息'
          return
        }
        const timeFlag = hasOverlap(editData.value)
        console.log('timeFlag', timeFlag);
        if (timeFlag) {
          // message.type = MESSAGE_TYPE.ALERT
          // message.text = `时间段${timeFlag.time}与其他时段发生时间重叠，请检查修改`
          // alert(`时间段${timeFlag.time}与其他时段发生时间重叠，请检查修改`)
          alert.type = MESSAGE_TYPE.ALERT
          alert.text = `时间段${timeFlag.time}与其他时段发生时间重叠，请检查修改`
          return
        }
        alert.type = MESSAGE_TYPE.CONFIRM
        alert.text = '确定保存时段信息吗?'
        alert.methods = 'confirmSave'
      }

      const confirmSave = () => {
        alert.text = ''
        alert.type = ''
        loading.save = true
        // const otherData = originData.value.filter(item => item.master != editData.value[0].master)
        // const resultData = [].concat(otherData).concat(editData.value)
        let submitData = editData.value.map((item) => {
          return { master: item.master, time: item.time, plno: item.plno, enable: item.enable }
        })
        submitData = submitData.filter(item => item.plno)
        fetch(`${apiPreFix.value}${api.value.setEnableTime}`, {
          method: 'POST',
          body: JSON.stringify(submitData),
          headers: {
            'content-type': 'application/json'
          }
        })
          .then(res => res.json())
          .then(res => {
            if (!res.err) {
              message.text = `编辑成功`
              message.type = MESSAGE_TYPE.SUCCESS
              getTimeConfig()
              editData.value = []
            }
            else {
              message.text = res.err || `编辑失败`
              message.type = MESSAGE_TYPE.ERROR
            }
            if (res.code === 401) {
              goLogin()
            }
          })
          .catch((res) => {
            message.text = res.err || `编辑失败`
            message.type = MESSAGE_TYPE.ERROR
          })
          .finally((res) => {
            loading.save = false
          })
      }

      const defaultTimeItem = {
        master: '', time: '', plno: '', enable: false, startTime: '', endTime: ''
      }

      const schemeList = ref([])
      // 获取子区的方案信息
      const getCrossScheme = () => {
        fetch(`${apiPreFix.value}${api.value.getPlans}`)
          .then(res => res.json())
          .then(res => {
            schemeList.value = res
          })
      }

      const canUseScheme = ref([])
      // 当前方案列表
      const currentPlnoList = () => {
        canUseScheme.value = []
        const list = schemeList.value.filter(item => item.site == editData.value[0].master)
        const ids = list.map(item => item.plno) || []
        SCHEME_CONFIG.forEach(item => {
          canUseScheme.value.push({
            key: item,
            disabled: !ids.includes(item)
          })
        })

      }

      // 增加一行时段数据
      const handleAdd = (index) => {
        editData.value.splice(index + 1, 0, {
          ...defaultTimeItem,
          master: editData.value[0].master
        })
      }

      // 删除一行时段数据
      const handleRemove = (index) => {
        // 如果是最后一行数据，那么清空数据
        if (editData.value.length <= 1) {
          editData.value[0] = {
            ...defaultTimeItem,
            master: editData.value[0].master
          }
          return
        }
        editData.value.splice(index, 1)
      }

      // 时间发生改变
      const handleChangeTime = (item, key) => {
        // 如果开始时间大于结束时间，那么将两个时间交换
        if (item.startTime && item.endTime) {
          if (dateInit(item.startTime) > dateInit(item.endTime)) {
            // const temp = JSON.parse(JSON.stringify(item))
            // item.endTime = item.startTime
            // item.startTime = temp.endTime
            message.type = MESSAGE_TYPE.ALERT
            message.text = key === 'startTime' ? '开始时间不能大于结束时间' : '结束时间不能小于开始时间'
            item[key] = ''
          }
        }
      }

      const cancelConfirm = () => {
        alert.type = ''
        alert.text = ''
        alert.methods = ''
        alert.item = ''
      }

      // 确认操作
      const handleConfirm = async (alert) => {
        console.log('methodsList[key]', methodsList[alert.methods]);
        try {
          await methodsList[alert.methods](alert.item)
          cancelConfirm()
        } catch {
          cancelConfirm()
        }
      }

      const handleLoginOut = () => {
        alert.text = `确定退出登录吗?`
        alert.type = MESSAGE_TYPE.CONFIRM
        alert.methods = 'goLogin'
      }

      const methodsList = {
        'goLogin': goLogin,
        'confirmSave': confirmSave
      }

      const SUB_LIST = ref([])
      const TIME_LIST = ref([])
      const subData = ref([])
      onMounted(() => {
        hasLogin(apiPreFix.value)
        const sessionData = JSON.parse(window.sessionStorage.getItem('BASE_DICTS'))
        if (!sessionData) {
          window.location.replace(window.location.origin)
          const currentPage = pageTab.find(item => item.key === 'time-config')
          currentPage && window.sessionStorage.setItem('CURRENT_PAGE', JSON.stringify(currentPage))
        }
        subData.value = sessionData.areas
        SUB_LIST.value = sessionData.areas
        TIME_LIST.value = sessionData.times
        getTimeConfig()
        getCrossScheme()
      })
      return {
        timeConfigList,
        loading,
        message,
        MESSAGE_TYPE,
        PAGE_TYPE,
        editData,
        SCHEME_CONFIG,
        canUseScheme,
        pageTab,
        changeTab,
        isOdd,
        alert,
        handleChangeTime,
        handleEdit,
        handleClose,
        handleSave,
        handleAdd,
        handleRemove,
        handleLoginOut,
        cancelConfirm,
        handleConfirm
      }
    }
  })
  app.mount("#time-config");
</script>

</html>